gtkappchoosermodule.c \
gtkappchooseronline.c \
gtkapplication.c \
+ gtkapplicationimpl.c \
gtkapplicationwindow.c \
gtkarrow.c \
gtkaspectframe.c \
gtksocket.c \
gtkxembed.c \
gtktrayicon-x11.c \
+ gtkapplication-x11.c \
gtkmountoperation-x11.c
+
+gtk_use_wayland_c_sources = \
+ gtkapplication-wayland.c
+
+gtk_use_wayland_or_x11_c_sources = \
+ gtkapplication-dbus.c
+
gtk_use_win32_c_sources = \
gtkwin32embed.c \
gtkwin32embedwidget.c \
gtksearchenginequartz.c \
gtkmountoperation-stub.c \
gtkmodelmenu-quartz.c \
+ gtkapplication-quartz.c \
gtkquartz.c
gtk_use_stub_c_sources = \
gtkmountoperation-stub.c
gtk_private_h_sources += $(gtk_use_x11_private_h_sources)
endif
+if USE_WAYLAND
+gtk_c_sources += $(gtk_use_wayland_c_sources)
+endif
+
+# pretty tricky way to write USE_WAYLAND || USE_X11...
+if USE_WAYLAND
+gtk_c_sources += $(gtk_use_wayland_or_x11_c_sources)
+else
+if USE_X11
+gtk_c_sources += $(gtk_use_wayland_or_x11_c_sources)
+else
+endif
+endif
+
gtk_use_win32_private_h_sources = \
gtkwin32embed.h \
gtkwin32embedwidget.h
--- /dev/null
+/*
+ * Copyright © 2010 Codethink Limited
+ * Copyright © 2012 Red Hat, Inc.
+ * Copyright © 2013 Canonical Limited
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ * Matthias Clasen <mclasen@redhat.com>
+ */
+
+#include "config.h"
+
+#include "gtkapplicationprivate.h"
+
+G_DEFINE_TYPE (GtkApplicationImplDBus, gtk_application_impl_dbus, GTK_TYPE_APPLICATION_IMPL)
+
+
+static void
+unregister_client (GtkApplicationImplDBus *dbus)
+{
+ GError *error = NULL;
+
+ g_debug ("Unregistering client");
+
+ g_dbus_proxy_call_sync (dbus->sm_proxy,
+ "UnregisterClient",
+ g_variant_new ("(o)", dbus->client_path),
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT,
+ NULL,
+ &error);
+
+ if (error)
+ {
+ g_warning ("Failed to unregister client: %s", error->message);
+ g_error_free (error);
+ }
+
+ g_clear_object (&dbus->client_proxy);
+
+ g_free (dbus->client_path);
+ dbus->client_path = NULL;
+}
+
+static void
+send_quit_response (GtkApplicationImplDBus *dbus,
+ gboolean will_quit,
+ const gchar *reason)
+{
+ g_debug ("Calling EndSessionResponse %d '%s'", will_quit, reason);
+
+ g_dbus_proxy_call (dbus->client_proxy,
+ "EndSessionResponse",
+ g_variant_new ("(bs)", will_quit, reason ? reason : ""),
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT,
+ NULL, NULL, NULL);
+}
+
+static void
+client_proxy_signal (GDBusProxy *proxy,
+ const gchar *sender_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ GtkApplicationImplDBus *dbus = user_data;
+
+ if (g_str_equal (signal_name, "QueryEndSession"))
+ {
+ g_debug ("Received QueryEndSession");
+ send_quit_response (dbus, TRUE, NULL);
+ }
+ else if (g_str_equal (signal_name, "CancelEndSession"))
+ {
+ g_debug ("Received CancelEndSession");
+ }
+ else if (g_str_equal (signal_name, "EndSession"))
+ {
+ g_debug ("Received EndSession");
+ send_quit_response (dbus, TRUE, NULL);
+ unregister_client (dbus);
+ g_application_quit (G_APPLICATION (dbus->impl.application));
+ }
+ else if (g_str_equal (signal_name, "Stop"))
+ {
+ g_debug ("Received Stop");
+ unregister_client (dbus);
+ g_application_quit (G_APPLICATION (dbus->impl.application));
+ }
+}
+
+static void
+gtk_application_impl_dbus_startup (GtkApplicationImpl *impl,
+ gboolean register_session)
+{
+ GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) impl;
+ static gchar *client_id;
+ GError *error = NULL;
+ GVariant *res;
+
+ dbus->session = g_application_get_dbus_connection (G_APPLICATION (impl->application));
+
+ if (!dbus->session)
+ return;
+
+ dbus->application_id = g_application_get_application_id (G_APPLICATION (impl->application));
+ dbus->object_path = g_application_get_dbus_object_path (G_APPLICATION (impl->application));
+ dbus->unique_name = g_dbus_connection_get_unique_name (dbus->session);
+
+ if (client_id == NULL)
+ {
+ const gchar *desktop_autostart_id;
+
+ desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
+ /* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to
+ * use the same client id.
+ */
+ g_unsetenv ("DESKTOP_AUTOSTART_ID");
+ client_id = g_strdup (desktop_autostart_id ? desktop_autostart_id : "");
+ }
+
+ g_debug ("Connecting to session manager");
+
+ dbus->sm_proxy = g_dbus_proxy_new_sync (dbus->session,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
+ G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+ NULL,
+ "org.gnome.SessionManager",
+ "/org/gnome/SessionManager",
+ "org.gnome.SessionManager",
+ NULL,
+ &error);
+
+ if (error)
+ {
+ g_warning ("Failed to get a session proxy: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ /* FIXME: should we reuse the D-Bus application id here ? */
+ dbus->app_id = g_strdup (g_get_prgname ());
+
+ if (!register_session)
+ return;
+
+ g_debug ("Registering client '%s' '%s'", dbus->app_id, client_id);
+
+ res = g_dbus_proxy_call_sync (dbus->sm_proxy,
+ "RegisterClient",
+ g_variant_new ("(ss)", dbus->app_id, client_id),
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT,
+ NULL,
+ &error);
+
+ if (error)
+ {
+ g_warning ("Failed to register client: %s", error->message);
+ g_error_free (error);
+ g_clear_object (&dbus->sm_proxy);
+ return;
+ }
+
+ g_variant_get (res, "(o)", &dbus->client_path);
+ g_variant_unref (res);
+
+ g_debug ("Registered client at '%s'", dbus->client_path);
+
+ dbus->client_proxy = g_dbus_proxy_new_sync (dbus->session, 0,
+ NULL,
+ "org.gnome.SessionManager",
+ dbus->client_path,
+ "org.gnome.SessionManager.ClientPrivate",
+ NULL,
+ &error);
+ if (error)
+ {
+ g_warning ("Failed to get client proxy: %s", error->message);
+ g_error_free (error);
+ g_clear_object (&dbus->sm_proxy);
+ g_free (dbus->client_path);
+ dbus->client_path = NULL;
+ return;
+ }
+
+ g_signal_connect (dbus->client_proxy, "g-signal", G_CALLBACK (client_proxy_signal), dbus);
+}
+
+static void
+gtk_application_impl_dbus_shutdown (GtkApplicationImpl *impl)
+{
+}
+
+G_DEFINE_QUARK (GtkApplicationImplDBus export id, gtk_application_impl_dbus_export_id)
+
+static void
+gtk_application_impl_dbus_window_added (GtkApplicationImpl *impl,
+ GtkWindow *window)
+{
+ GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) impl;
+ GActionGroup *actions;
+ gchar *path;
+ guint id;
+
+ if (!dbus->session || !GTK_IS_APPLICATION_WINDOW (window))
+ return;
+
+ /* Export the action group of this window, based on its id */
+ actions = gtk_application_window_get_action_group (GTK_APPLICATION_WINDOW (window));
+
+ path = gtk_application_impl_dbus_get_window_path (dbus, window);
+ id = g_dbus_connection_export_action_group (dbus->session, path, actions, NULL);
+ g_free (path);
+
+ g_object_set_qdata (G_OBJECT (window), gtk_application_impl_dbus_export_id_quark (), GUINT_TO_POINTER (id));
+}
+
+static void
+gtk_application_impl_dbus_window_removed (GtkApplicationImpl *impl,
+ GtkWindow *window)
+{
+ GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) impl;
+ guint id;
+
+ id = GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (window), gtk_application_impl_dbus_export_id_quark ()));
+ if (id)
+ {
+ g_dbus_connection_unexport_action_group (dbus->session, id);
+ g_object_set_qdata (G_OBJECT (window), gtk_application_impl_dbus_export_id_quark (), NULL);
+ }
+}
+
+static void
+gtk_application_impl_dbus_active_window_changed (GtkApplicationImpl *impl,
+ GtkWindow *window)
+{
+}
+
+static void
+gtk_application_impl_dbus_publish_menu (GtkApplicationImplDBus *dbus,
+ const gchar *type,
+ GMenuModel *model,
+ guint *id,
+ gchar **path)
+{
+ gint i;
+
+ if (dbus->session == NULL)
+ return;
+
+ /* unexport any existing menu */
+ if (*id)
+ {
+ g_dbus_connection_unexport_menu_model (dbus->session, *id);
+ g_free (*path);
+ *path = NULL;
+ *id = 0;
+ }
+
+ /* export the new menu, if there is one */
+ if (model != NULL)
+ {
+ /* try getting the preferred name */
+ *path = g_strconcat (dbus->object_path, "/menus/", type, NULL);
+ *id = g_dbus_connection_export_menu_model (dbus->session, *path, model, NULL);
+
+ /* keep trying until we get a working name... */
+ for (i = 0; *id == 0; i++)
+ {
+ g_free (*path);
+ *path = g_strdup_printf ("%s/menus/%s%d", dbus->object_path, type, i);
+ *id = g_dbus_connection_export_menu_model (dbus->session, *path, model, NULL);
+ }
+ }
+}
+
+static void
+gtk_application_impl_dbus_set_app_menu (GtkApplicationImpl *impl,
+ GMenuModel *app_menu)
+{
+ GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) impl;
+
+ gtk_application_impl_dbus_publish_menu (dbus, "appmenu", app_menu, &dbus->app_menu_id, &dbus->app_menu_path);
+}
+
+static void
+gtk_application_impl_dbus_set_menubar (GtkApplicationImpl *impl,
+ GMenuModel *menubar)
+{
+ GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) impl;
+
+ gtk_application_impl_dbus_publish_menu (dbus, "menubar", menubar, &dbus->menubar_id, &dbus->menubar_path);
+}
+
+static GVariant *
+gtk_application_impl_dbus_real_get_window_system_id (GtkApplicationImplDBus *dbus,
+ GtkWindow *window)
+{
+ return g_variant_new_uint32 (0);
+}
+
+/* returns floating */
+static GVariant *
+gtk_application_impl_dbus_get_window_system_id (GtkApplicationImplDBus *dbus,
+ GtkWindow *window)
+{
+ return GTK_APPLICATION_IMPL_DBUS_GET_CLASS (dbus)->get_window_system_id (dbus, window);
+}
+
+static guint
+gtk_application_impl_dbus_inhibit (GtkApplicationImpl *impl,
+ GtkWindow *window,
+ GtkApplicationInhibitFlags flags,
+ const gchar *reason)
+{
+ GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) impl;
+ GVariant *res;
+ GError *error = NULL;
+ guint cookie;
+
+ if (dbus->sm_proxy == NULL)
+ return 0;
+
+ res = g_dbus_proxy_call_sync (dbus->sm_proxy,
+ "Inhibit",
+ g_variant_new ("(s@usu)",
+ g_application_get_application_id (G_APPLICATION (impl->application)),
+ gtk_application_impl_dbus_get_window_system_id (dbus, window),
+ reason,
+ flags),
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT,
+ NULL,
+ &error);
+
+ if (error)
+ {
+ g_warning ("Calling Inhibit failed: %s", error->message);
+ g_error_free (error);
+ return 0;
+ }
+
+ g_variant_get (res, "(u)", &cookie);
+ g_variant_unref (res);
+
+ return cookie;
+
+}
+
+static void
+gtk_application_impl_dbus_uninhibit (GtkApplicationImpl *impl,
+ guint cookie)
+{
+ GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) impl;
+
+ /* Application could only obtain a cookie through a session
+ * manager proxy, so it's valid to assert its presence here. */
+ g_return_if_fail (dbus->sm_proxy != NULL);
+
+ g_dbus_proxy_call (dbus->sm_proxy,
+ "Uninhibit",
+ g_variant_new ("(u)", cookie),
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT,
+ NULL, NULL, NULL);
+}
+
+static gboolean
+gtk_application_impl_dbus_is_inhibited (GtkApplicationImpl *impl,
+ GtkApplicationInhibitFlags flags)
+{
+ GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) impl;
+ GVariant *res;
+ GError *error = NULL;
+ gboolean inhibited;
+
+ if (dbus->sm_proxy == NULL)
+ return FALSE;
+
+ res = g_dbus_proxy_call_sync (dbus->sm_proxy,
+ "IsInhibited",
+ g_variant_new ("(u)", flags),
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT,
+ NULL,
+ &error);
+ if (error)
+ {
+ g_warning ("Calling IsInhibited failed: %s", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ g_variant_get (res, "(b)", &inhibited);
+ g_variant_unref (res);
+
+ return inhibited;
+}
+
+static void
+gtk_application_impl_dbus_init (GtkApplicationImplDBus *dbus)
+{
+}
+
+static void
+gtk_application_impl_dbus_finalize (GObject *object)
+{
+ //GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) object;
+
+ G_OBJECT_CLASS (gtk_application_impl_dbus_parent_class)->finalize (object);
+}
+
+static void
+gtk_application_impl_dbus_class_init (GtkApplicationImplDBusClass *class)
+{
+ GtkApplicationImplClass *impl_class = GTK_APPLICATION_IMPL_CLASS (class);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+
+ class->get_window_system_id = gtk_application_impl_dbus_real_get_window_system_id;
+
+ impl_class->startup = gtk_application_impl_dbus_startup;
+ impl_class->shutdown = gtk_application_impl_dbus_shutdown;
+ impl_class->window_added = gtk_application_impl_dbus_window_added;
+ impl_class->window_removed = gtk_application_impl_dbus_window_removed;
+ impl_class->active_window_changed = gtk_application_impl_dbus_active_window_changed;
+ impl_class->set_app_menu = gtk_application_impl_dbus_set_app_menu;
+ impl_class->set_menubar = gtk_application_impl_dbus_set_menubar;
+ impl_class->inhibit = gtk_application_impl_dbus_inhibit;
+ impl_class->uninhibit = gtk_application_impl_dbus_uninhibit;
+ impl_class->is_inhibited = gtk_application_impl_dbus_is_inhibited;
+
+ gobject_class->finalize = gtk_application_impl_dbus_finalize;
+}
+
+gchar *
+gtk_application_impl_dbus_get_window_path (GtkApplicationImplDBus *dbus,
+ GtkWindow *window)
+{
+ if (dbus->session && GTK_IS_APPLICATION_WINDOW (window))
+ return g_strdup_printf ("%s/window/%d",
+ dbus->object_path,
+ gtk_application_window_get_id (GTK_APPLICATION_WINDOW (window)));
+ else
+ return NULL;
+}
--- /dev/null
+/*
+ * Copyright © 2010 Codethink Limited
+ * Copyright © 2013 Canonical Limited
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "config.h"
+
+#include "gtkapplicationprivate.h"
+#include "gtkmodelmenu-quartz.h"
+#include "gtkmessagedialog.h"
+#include <glib/gi18n-lib.h>
+#import <Cocoa/Cocoa.h>
+
+typedef struct
+{
+ guint cookie;
+ GtkApplicationInhibitFlags flags;
+ char *reason;
+ GtkWindow *window;
+} GtkApplicationQuartzInhibitor;
+
+static void
+gtk_application_quartz_inhibitor_free (GtkApplicationQuartzInhibitor *inhibitor)
+{
+ g_free (inhibitor->reason);
+ g_clear_object (&inhibitor->window);
+ g_slice_free (GtkApplicationQuartzInhibitor, inhibitor);
+}
+
+typedef GtkApplicationImplClass GtkApplicationImplQuartzClass;
+
+typedef struct
+{
+ GtkApplicationImpl impl;
+
+ GSList *inhibitors;
+ gint quit_inhibit;
+ guint next_cookie;
+} GtkApplicationImplQuartz;
+
+G_DEFINE_TYPE (GtkApplicationImplQuartz, gtk_application_impl_quartz, GTK_TYPE_APPLICATION_IMPL)
+
+/* OS X implementation copied from EggSMClient, but simplified since
+ * it doesn't need to interact with the user.
+ */
+
+static gboolean
+idle_will_quit (gpointer user_data)
+{
+ GtkApplicationImplQuartz *quartz = user_data;
+
+ if (quartz->quit_inhibit == 0)
+ g_application_quit (G_APPLICATION (quartz->impl.application));
+ else
+ {
+ GtkApplicationQuartzInhibitor *inhibitor;
+ GSList *iter;
+ GtkWidget *dialog;
+
+ for (iter = quartz->inhibitors; iter; iter = iter->next)
+ {
+ inhibitor = iter->data;
+ if (inhibitor->flags & GTK_APPLICATION_INHIBIT_LOGOUT)
+ break;
+ }
+ g_assert (inhibitor != NULL);
+
+ dialog = gtk_message_dialog_new (inhibitor->window,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ _("%s cannot quit at this time:\n\n%s"),
+ g_get_application_name (),
+ inhibitor->reason);
+ g_signal_connect_swapped (dialog,
+ "response",
+ G_CALLBACK (gtk_widget_destroy),
+ dialog);
+ gtk_widget_show_all (dialog);
+ }
+
+ return G_SOURCE_REMOVE;
+}
+
+static pascal OSErr
+quit_requested (const AppleEvent *aevt,
+ AppleEvent *reply,
+ long refcon)
+{
+ GtkApplicationImplQuartz *quartz = GSIZE_TO_POINTER ((gsize)refcon);
+
+ /* Don't emit the "quit" signal immediately, since we're
+ * called from a weird point in the guts of gdkeventloop-quartz.c
+ */
+ g_idle_add_full (G_PRIORITY_DEFAULT, idle_will_quit, quartz, NULL);
+
+ return quartz->quit_inhibit == 0 ? noErr : userCanceledErr;
+}
+
+static void
+gtk_application_impl_quartz_menu_changed (GtkApplicationImplQuartz *quartz)
+{
+ GMenu *combined;
+
+ combined = g_menu_new ();
+ g_menu_append_submenu (combined, "Application", gtk_application_get_app_menu (quartz->impl.application));
+ g_menu_append_section (combined, NULL, gtk_application_get_menubar (quartz->impl.application));
+
+ gtk_quartz_set_main_menu (G_MENU_MODEL (combined), quartz->impl.application);
+
+ g_object_unref (combined);
+}
+
+static void
+gtk_application_impl_quartz_startup (GtkApplicationImpl *impl,
+ gboolean register_session)
+{
+ GtkApplicationImplQuartz *quartz = (GtkApplicationImplQuartz *) impl;
+
+ if (register_session)
+ AEInstallEventHandler (kCoreEventClass, kAEQuitApplication,
+ NewAEEventHandlerUPP (quit_requested),
+ (long)GPOINTER_TO_SIZE (quartz), false);
+
+ gtk_application_impl_quartz_menu_changed (quartz);
+
+ [NSApp finishLaunching];
+}
+
+static void
+gtk_application_impl_quartz_shutdown (GtkApplicationImpl *impl)
+{
+ GtkApplicationImplQuartz *quartz = (GtkApplicationImplQuartz *) impl;
+
+ gtk_quartz_clear_main_menu ();
+
+ g_slist_free_full (quartz->inhibitors, (GDestroyNotify) gtk_application_quartz_inhibitor_free);
+ quartz->inhibitors = NULL;
+}
+
+static void
+gtk_application_impl_quartz_set_app_menu (GtkApplicationImpl *impl,
+ GMenuModel *app_menu)
+{
+ GtkApplicationImplQuartz *quartz = (GtkApplicationImplQuartz *) impl;
+
+ gtk_application_impl_quartz_menu_changed (quartz);
+}
+
+static void
+gtk_application_impl_quartz_set_menubar (GtkApplicationImpl *impl,
+ GMenuModel *menubar)
+{
+ GtkApplicationImplQuartz *quartz = (GtkApplicationImplQuartz *) impl;
+
+ gtk_application_impl_quartz_menu_changed (quartz);
+}
+
+static guint
+gtk_application_impl_quartz_inhibit (GtkApplicationImpl *impl,
+ GtkWindow *window,
+ GtkApplicationInhibitFlags flags,
+ const gchar *reason)
+{
+ GtkApplicationImplQuartz *quartz = (GtkApplicationImplQuartz *) impl;
+ GtkApplicationQuartzInhibitor *inhibitor;
+
+ inhibitor = g_slice_new (GtkApplicationQuartzInhibitor);
+ inhibitor->cookie = ++quartz->next_cookie;
+ inhibitor->flags = flags;
+ inhibitor->reason = g_strdup (reason);
+ inhibitor->window = window ? g_object_ref (window) : NULL;
+
+ quartz->inhibitors = g_slist_prepend (quartz->inhibitors, inhibitor);
+
+ if (flags & GTK_APPLICATION_INHIBIT_LOGOUT)
+ quartz->quit_inhibit++;
+
+ return inhibitor->cookie;
+}
+
+static void
+gtk_application_impl_quartz_uninhibit (GtkApplicationImpl *impl,
+ guint cookie)
+{
+ GtkApplicationImplQuartz *quartz = (GtkApplicationImplQuartz *) impl;
+ GSList *iter;
+
+ for (iter = quartz->inhibitors; iter; iter = iter->next)
+ {
+ GtkApplicationQuartzInhibitor *inhibitor = iter->data;
+
+ if (inhibitor->cookie == cookie)
+ {
+ if (inhibitor->flags & GTK_APPLICATION_INHIBIT_LOGOUT)
+ quartz->quit_inhibit--;
+ gtk_application_quartz_inhibitor_free (inhibitor);
+ quartz->inhibitors = g_slist_delete_link (quartz->inhibitors, iter);
+ return;
+ }
+ }
+
+ g_warning ("Invalid inhibitor cookie");
+}
+
+static gboolean
+gtk_application_impl_quartz_is_inhibited (GtkApplicationImpl *impl,
+ GtkApplicationInhibitFlags flags)
+{
+ GtkApplicationImplQuartz *quartz = (GtkApplicationImplQuartz *) impl;
+
+ if (flags & GTK_APPLICATION_INHIBIT_LOGOUT)
+ return quartz->quit_inhibit > 0;
+
+ return FALSE;
+}
+
+static void
+gtk_application_impl_quartz_init (GtkApplicationImplQuartz *quartz)
+{
+}
+
+static void
+gtk_application_impl_quartz_finalize (GObject *object)
+{
+ GtkApplicationImplQuartz *quartz = (GtkApplicationImplQuartz *) object;
+
+ g_slist_free_full (quartz->inhibitors, (GDestroyNotify) gtk_application_quartz_inhibitor_free);
+
+ G_OBJECT_CLASS (gtk_application_impl_quartz_parent_class)->finalize (object);
+}
+
+static void
+gtk_application_impl_quartz_class_init (GtkApplicationImplClass *class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+
+ class->startup = gtk_application_impl_quartz_startup;
+ class->shutdown = gtk_application_impl_quartz_shutdown;
+ class->set_app_menu = gtk_application_impl_quartz_set_app_menu;
+ class->set_menubar = gtk_application_impl_quartz_set_menubar;
+ class->inhibit = gtk_application_impl_quartz_inhibit;
+ class->uninhibit = gtk_application_impl_quartz_uninhibit;
+ class->is_inhibited = gtk_application_impl_quartz_is_inhibited;
+
+ gobject_class->finalize = gtk_application_impl_quartz_finalize;
+}
--- /dev/null
+/*
+ * Copyright © 2010 Codethink Limited
+ * Copyright © 2013 Canonical Limited
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "config.h"
+
+#include "gtkapplicationprivate.h"
+
+#include <gdk/wayland/gdkwayland.h>
+
+typedef GtkApplicationImplDBusClass GtkApplicationImplWaylandClass;
+
+typedef struct
+{
+ GtkApplicationImplDBus dbus;
+
+} GtkApplicationImplWayland;
+
+G_DEFINE_TYPE (GtkApplicationImplWayland, gtk_application_impl_wayland, GTK_TYPE_APPLICATION_IMPL_DBUS)
+
+static void
+gtk_application_impl_wayland_handle_window_map (GtkApplicationImpl *impl,
+ GtkWindow *window)
+{
+ GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) impl;
+ GdkWindow *gdk_window;
+ gchar *window_path;
+
+ gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
+
+ if (!GDK_IS_WAYLAND_WINDOW (gdk_window))
+ return;
+
+ window_path = gtk_application_impl_dbus_get_window_path (dbus, window);
+
+ gdk_wayland_window_set_dbus_properties_libgtk_only (gdk_window,
+ dbus->application_id, dbus->app_menu_path, dbus->menubar_path,
+ window_path, dbus->object_path, dbus->unique_name);
+
+ g_free (window_path);
+}
+
+static void
+gtk_application_impl_wayland_init (GtkApplicationImplWayland *wayland)
+{
+}
+
+static void
+gtk_application_impl_wayland_class_init (GtkApplicationImplWaylandClass *class)
+{
+ GtkApplicationImplClass *impl_class = GTK_APPLICATION_IMPL_CLASS (class);
+
+ impl_class->handle_window_map = gtk_application_impl_wayland_handle_window_map;
+}
--- /dev/null
+/*
+ * Copyright © 2010 Codethink Limited
+ * Copyright © 2013 Canonical Limited
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "config.h"
+
+#include "gtkapplicationprivate.h"
+
+#include <gdk/gdkx.h>
+
+typedef GtkApplicationImplDBusClass GtkApplicationImplX11Class;
+
+typedef struct
+{
+ GtkApplicationImplDBus dbus;
+
+} GtkApplicationImplX11;
+
+G_DEFINE_TYPE (GtkApplicationImplX11, gtk_application_impl_x11, GTK_TYPE_APPLICATION_IMPL_DBUS)
+
+static void
+gtk_application_impl_x11_handle_window_realize (GtkApplicationImpl *impl,
+ GtkWindow *window)
+{
+ GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) impl;
+ GdkWindow *gdk_window;
+ gchar *window_path;
+
+ gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
+
+ if (!GDK_IS_X11_WINDOW (gdk_window))
+ return;
+
+ window_path = gtk_application_impl_dbus_get_window_path (dbus, window);
+
+ gdk_x11_window_set_utf8_property (gdk_window, "_GTK_APPLICATION_ID", dbus->application_id);
+ gdk_x11_window_set_utf8_property (gdk_window, "_GTK_UNIQUE_BUS_NAME", dbus->unique_name);
+ gdk_x11_window_set_utf8_property (gdk_window, "_GTK_APPLICATION_OBJECT_PATH", dbus->object_path);
+ gdk_x11_window_set_utf8_property (gdk_window, "_GTK_WINDOW_OBJECT_PATH", window_path);
+ gdk_x11_window_set_utf8_property (gdk_window, "_GTK_APP_MENU_OBJECT_PATH", dbus->app_menu_path);
+ gdk_x11_window_set_utf8_property (gdk_window, "_GTK_MENUBAR_OBJECT_PATH", dbus->menubar_path);
+
+ g_free (window_path);
+}
+
+static GVariant *
+gtk_application_impl_x11_get_window_system_id (GtkApplicationImplDBus *dbus,
+ GtkWindow *window)
+{
+ GdkWindow *gdk_window;
+
+ gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
+
+ if (GDK_IS_X11_WINDOW (gdk_window))
+ return g_variant_new_uint32 (GDK_WINDOW_XID (gdk_window));
+
+ return GTK_APPLICATION_IMPL_DBUS_CLASS (gtk_application_impl_x11_parent_class)->get_window_system_id (dbus, window);
+}
+
+static void
+gtk_application_impl_x11_init (GtkApplicationImplX11 *x11)
+{
+}
+
+static void
+gtk_application_impl_x11_class_init (GtkApplicationImplX11Class *class)
+{
+ GtkApplicationImplDBusClass *dbus_class = GTK_APPLICATION_IMPL_DBUS_CLASS (class);
+ GtkApplicationImplClass *impl_class = GTK_APPLICATION_IMPL_CLASS (class);
+
+ impl_class->handle_window_realize = gtk_application_impl_x11_handle_window_realize;
+ dbus_class->get_window_system_id = gtk_application_impl_x11_get_window_system_id;
+}
/*
* Copyright © 2010 Codethink Limited
+ * Copyright © 2013 Canonical Limited
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#include "gtkapplication.h"
#include <stdlib.h>
-#ifdef HAVE_UNISTD_H
#include <unistd.h>
-#endif
#include <string.h>
#include "gtkapplicationprivate.h"
#include "gtkmain.h"
#include "gtkrecentmanager.h"
#include "gtkaccelmapprivate.h"
+#include "gtkbuilder.h"
#include "gtkintl.h"
-#ifdef GDK_WINDOWING_QUARTZ
-#include "gtkmodelmenu-quartz.h"
-#import <Cocoa/Cocoa.h>
-#include <Carbon/Carbon.h>
-#include "gtkmessagedialog.h"
-#endif
-
-#include <gdk/gdk.h>
-#ifdef GDK_WINDOWING_X11
-#include <gdk/x11/gdkx.h>
-#endif
+/* NB: please do not add backend-specific GDK headers here. This should
+ * be abstracted via GtkApplicationImpl.
+ */
/**
* SECTION:gtkapplication
struct _GtkApplicationPrivate
{
+ GtkApplicationImpl *impl;
+
GList *windows;
GMenuModel *app_menu;
GMenuModel *menubar;
Accels accels;
+ guint last_window_id;
gboolean register_session;
GtkActionMuxer *muxer;
-
-#ifdef GDK_WINDOWING_X11
- guint next_id;
-
- GDBusConnection *session_bus;
- const gchar *application_id;
- const gchar *object_path;
-
- gchar *app_menu_path;
- guint app_menu_id;
-
- guint menubar_id;
- gchar *menubar_path;
-
- GDBusProxy *sm_proxy;
- GDBusProxy *client_proxy;
- gchar *app_id;
- gchar *client_path;
-#endif
-
-#ifdef GDK_WINDOWING_QUARTZ
- GMenu *combined;
-
- GSList *inhibitors;
- gint quit_inhibit;
- guint next_cookie;
-#endif
};
G_DEFINE_TYPE_WITH_PRIVATE (GtkApplication, gtk_application, G_TYPE_APPLICATION)
-#ifdef GDK_WINDOWING_X11
-static void
-gtk_application_x11_publish_menu (GtkApplication *application,
- const gchar *type,
- GMenuModel *model,
- guint *id,
- gchar **path)
-{
- gint i;
-
- if (application->priv->session_bus == NULL)
- return;
-
- /* unexport any existing menu */
- if (*id)
- {
- g_dbus_connection_unexport_menu_model (application->priv->session_bus, *id);
- g_free (*path);
- *path = NULL;
- *id = 0;
- }
-
- /* export the new menu, if there is one */
- if (model != NULL)
- {
- /* try getting the preferred name */
- *path = g_strconcat (application->priv->object_path, "/menus/", type, NULL);
- *id = g_dbus_connection_export_menu_model (application->priv->session_bus, *path, model, NULL);
-
- /* keep trying until we get a working name... */
- for (i = 0; *id == 0; i++)
- {
- g_free (*path);
- *path = g_strdup_printf ("%s/menus/%s%d", application->priv->object_path, type, i);
- *id = g_dbus_connection_export_menu_model (application->priv->session_bus, *path, model, NULL);
- }
- }
-}
-
-static void
-gtk_application_set_app_menu_x11 (GtkApplication *application,
- GMenuModel *app_menu)
-{
- gtk_application_x11_publish_menu (application, "appmenu", app_menu,
- &application->priv->app_menu_id,
- &application->priv->app_menu_path);
-}
-
-static void
-gtk_application_set_menubar_x11 (GtkApplication *application,
- GMenuModel *menubar)
-{
- gtk_application_x11_publish_menu (application, "menubar", menubar,
- &application->priv->menubar_id,
- &application->priv->menubar_path);
-}
-
-static void
-gtk_application_window_added_x11 (GtkApplication *application,
- GtkWindow *window)
-{
- if (application->priv->session_bus == NULL)
- return;
-
- if (GTK_IS_APPLICATION_WINDOW (window))
- {
- GtkApplicationWindow *app_window = GTK_APPLICATION_WINDOW (window);
- gboolean success;
-
- /* GtkApplicationWindow associates with us when it is first created,
- * so surely it's not realized yet...
- */
- g_assert (!gtk_widget_get_realized (GTK_WIDGET (window)));
-
- do
- {
- gchar *window_path;
- guint window_id;
-
- window_id = application->priv->next_id++;
- window_path = g_strdup_printf ("%s/window/%u", application->priv->object_path, window_id);
- success = gtk_application_window_publish (app_window, application->priv->session_bus, window_path, window_id);
- g_free (window_path);
- }
- while (!success);
- }
-}
-
-static void
-gtk_application_window_removed_x11 (GtkApplication *application,
- GtkWindow *window)
-{
- if (application->priv->session_bus == NULL)
- return;
-
- if (GTK_IS_APPLICATION_WINDOW (window))
- gtk_application_window_unpublish (GTK_APPLICATION_WINDOW (window));
-}
-
-static void gtk_application_startup_session_dbus (GtkApplication *app);
-
-static void
-gtk_application_startup_x11 (GtkApplication *application)
-{
- application->priv->session_bus = g_application_get_dbus_connection (G_APPLICATION (application));
- application->priv->object_path = g_application_get_dbus_object_path (G_APPLICATION (application));
-
- gtk_application_startup_session_dbus (GTK_APPLICATION (application));
-}
-
-static void
-gtk_application_shutdown_x11 (GtkApplication *application)
-{
- gtk_application_set_app_menu_x11 (application, NULL);
- gtk_application_set_menubar_x11 (application, NULL);
-
- application->priv->session_bus = NULL;
- application->priv->object_path = NULL;
-
- g_clear_object (&application->priv->sm_proxy);
- g_clear_object (&application->priv->client_proxy);
- g_free (application->priv->app_id);
- g_free (application->priv->client_path);
-}
-
const gchar *
gtk_application_get_app_menu_object_path (GtkApplication *application)
{
- return application->priv->app_menu_path;
+ g_assert_not_reached (); /* XXX */
}
const gchar *
gtk_application_get_menubar_object_path (GtkApplication *application)
{
- return application->priv->menubar_path;
-}
-
-#endif
-
-#ifdef GDK_WINDOWING_QUARTZ
-
-typedef struct {
- guint cookie;
- GtkApplicationInhibitFlags flags;
- char *reason;
- GtkWindow *window;
-} GtkApplicationQuartzInhibitor;
-
-static void
-gtk_application_quartz_inhibitor_free (GtkApplicationQuartzInhibitor *inhibitor)
-{
- g_free (inhibitor->reason);
- g_clear_object (&inhibitor->window);
- g_slice_free (GtkApplicationQuartzInhibitor, inhibitor);
+ g_assert_not_reached (); /* XXX */
}
-static void
-gtk_application_menu_changed_quartz (GObject *object,
- GParamSpec *pspec,
- gpointer user_data)
-{
- GtkApplication *application = GTK_APPLICATION (object);
- GMenu *combined;
-
- combined = g_menu_new ();
- g_menu_append_submenu (combined, "Application", gtk_application_get_app_menu (application));
- g_menu_append_section (combined, NULL, gtk_application_get_menubar (application));
-
- gtk_quartz_set_main_menu (G_MENU_MODEL (combined), application);
-
- g_object_unref (combined);
-}
-
-static void gtk_application_startup_session_quartz (GtkApplication *app);
-
-static void
-gtk_application_startup_quartz (GtkApplication *application)
-{
- [NSApp finishLaunching];
-
- g_signal_connect (application, "notify::app-menu", G_CALLBACK (gtk_application_menu_changed_quartz), NULL);
- g_signal_connect (application, "notify::menubar", G_CALLBACK (gtk_application_menu_changed_quartz), NULL);
- gtk_application_menu_changed_quartz (G_OBJECT (application), NULL, NULL);
-
- gtk_application_startup_session_quartz (application);
-}
-
-static void
-gtk_application_shutdown_quartz (GtkApplication *application)
-{
- gtk_quartz_clear_main_menu ();
-
- g_signal_handlers_disconnect_by_func (application, gtk_application_menu_changed_quartz, NULL);
-
- g_slist_free_full (application->priv->inhibitors,
- (GDestroyNotify) gtk_application_quartz_inhibitor_free);
- application->priv->inhibitors = NULL;
-}
-#endif
-
static gboolean
gtk_application_focus_in_event_cb (GtkWindow *window,
GdkEventFocus *event,
priv->windows = g_list_concat (link, priv->windows);
}
+ gtk_application_impl_active_window_changed (application->priv->impl, window);
g_object_notify (G_OBJECT (application), "active-window");
return FALSE;
gtk_init (0, 0);
-#ifdef GDK_WINDOWING_X11
- gtk_application_startup_x11 (application);
-#endif
-
-#ifdef GDK_WINDOWING_QUARTZ
- gtk_application_startup_quartz (application);
-#endif
+ application->priv->impl = gtk_application_impl_new (application, gdk_display_get_default ());
+ gtk_application_impl_startup (application->priv->impl, application->priv->register_session);
}
static void
-gtk_application_shutdown (GApplication *application)
+gtk_application_shutdown (GApplication *g_application)
{
-#ifdef GDK_WINDOWING_X11
- gtk_application_shutdown_x11 (GTK_APPLICATION (application));
-#endif
+ GtkApplication *application = GTK_APPLICATION (g_application);
-#ifdef GDK_WINDOWING_QUARTZ
- gtk_application_shutdown_quartz (GTK_APPLICATION (application));
-#endif
+ gtk_application_impl_shutdown (application->priv->impl);
+ g_clear_object (&application->priv->impl);
/* Keep this section in sync with gtk_main() */
_gtk_recent_manager_sync ();
G_APPLICATION_CLASS (gtk_application_parent_class)
- ->shutdown (application);
+ ->shutdown (g_application);
}
static void
{
const gchar *startup_id;
+ /* This is slightly evil.
+ *
+ * We don't have an impl here because we're remote so we can't figure
+ * out what to do on a per-display-server basis.
+ *
+ * So we do all the things... which currently is just one thing.
+ */
startup_id = getenv ("DESKTOP_STARTUP_ID");
-
+
if (startup_id && g_utf8_validate (startup_id, -1, NULL))
g_variant_builder_add (builder, "{sv}", "desktop-startup-id",
g_variant_new_string (startup_id));
}
static void
-gtk_application_before_emit (GApplication *application,
+gtk_application_before_emit (GApplication *g_application,
GVariant *platform_data)
{
- GVariantIter iter;
- const gchar *key;
- GVariant *value;
+ GtkApplication *application = GTK_APPLICATION (g_application);
gdk_threads_enter ();
- g_variant_iter_init (&iter, platform_data);
- while (g_variant_iter_loop (&iter, "{&sv}", &key, &value))
- {
-#ifdef GDK_WINDOWING_X11
- if (strcmp (key, "desktop-startup-id") == 0)
- {
- GdkDisplay *display;
- const gchar *id;
-
- display = gdk_display_get_default ();
- id = g_variant_get_string (value, NULL);
- if (GDK_IS_X11_DISPLAY (display))
- gdk_x11_display_set_startup_notification_id (display, id);
- }
-#endif
- }
+ gtk_application_impl_before_emit (application->priv->impl, platform_data);
}
static void
application->priv->muxer = gtk_action_muxer_new ();
accels_init (&application->priv->accels);
-
-#ifdef GDK_WINDOWING_X11
- application->priv->next_id = 1;
-#endif
}
static void
{
GtkApplicationPrivate *priv = application->priv;
+ if (GTK_IS_APPLICATION_WINDOW (window))
+ gtk_application_window_set_id (GTK_APPLICATION_WINDOW (window), ++application->priv->last_window_id);
+
priv->windows = g_list_prepend (priv->windows, window);
gtk_window_set_application (window, application);
g_application_hold (G_APPLICATION (application));
G_CALLBACK (gtk_application_focus_in_event_cb),
application);
-#ifdef GDK_WINDOWING_X11
- gtk_application_window_added_x11 (application, window);
-#endif
+ gtk_application_impl_window_added (application->priv->impl, window);
+ gtk_application_impl_active_window_changed (application->priv->impl, window);
g_object_notify (G_OBJECT (application), "active-window");
}
old_active = priv->windows;
-#ifdef GDK_WINDOWING_X11
- gtk_application_window_removed_x11 (application, window);
-#endif
+ gtk_application_impl_window_removed (application->priv->impl, window);
g_signal_handlers_disconnect_by_func (window,
gtk_application_focus_in_event_cb,
gtk_window_set_application (window, NULL);
if (priv->windows != old_active)
- g_object_notify (G_OBJECT (application), "active-window");
+ {
+ gtk_application_impl_active_window_changed (application->priv->impl, priv->windows ? priv->windows->data : NULL);
+ g_object_notify (G_OBJECT (application), "active-window");
+ }
}
static void
if (app_menu)
extract_accels_from_menu (app_menu, application);
-#ifdef GDK_WINDOWING_X11
- gtk_application_set_app_menu_x11 (application, app_menu);
-#endif
+ gtk_application_impl_set_app_menu (application->priv->impl, app_menu);
g_object_notify (G_OBJECT (application), "app-menu");
}
if (menubar)
extract_accels_from_menu (menubar, application);
-#ifdef GDK_WINDOWING_X11
- gtk_application_set_menubar_x11 (application, menubar);
-#endif
+ gtk_application_impl_set_menubar (application->priv->impl, menubar);
g_object_notify (G_OBJECT (application), "menubar");
}
return application->priv->menubar;
}
-#if defined(GDK_WINDOWING_X11)
-
-/* D-Bus Session Management
- *
- * The protocol and the D-Bus API are described here:
- * http://live.gnome.org/SessionManagement/GnomeSession
- * http://people.gnome.org/~mccann/gnome-session/docs/gnome-session.html
- */
-
-static void
-unregister_client (GtkApplication *app)
-{
- GError *error = NULL;
-
- g_debug ("Unregistering client");
-
- g_dbus_proxy_call_sync (app->priv->sm_proxy,
- "UnregisterClient",
- g_variant_new ("(o)", app->priv->client_path),
- G_DBUS_CALL_FLAGS_NONE,
- G_MAXINT,
- NULL,
- &error);
-
- if (error)
- {
- g_warning ("Failed to unregister client: %s", error->message);
- g_error_free (error);
- }
-
- g_clear_object (&app->priv->client_proxy);
-
- g_free (app->priv->client_path);
- app->priv->client_path = NULL;
-}
-
-static void
-gtk_application_quit_response (GtkApplication *application,
- gboolean will_quit,
- const gchar *reason)
-{
- g_debug ("Calling EndSessionResponse %d '%s'", will_quit, reason);
-
- g_dbus_proxy_call (application->priv->client_proxy,
- "EndSessionResponse",
- g_variant_new ("(bs)", will_quit, reason ? reason : ""),
- G_DBUS_CALL_FLAGS_NONE,
- G_MAXINT,
- NULL, NULL, NULL);
-}
-static void
-client_proxy_signal (GDBusProxy *proxy,
- const gchar *sender_name,
- const gchar *signal_name,
- GVariant *parameters,
- GtkApplication *app)
-{
- if (strcmp (signal_name, "QueryEndSession") == 0)
- {
- g_debug ("Received QueryEndSession");
- gtk_application_quit_response (app, TRUE, NULL);
- }
- else if (strcmp (signal_name, "CancelEndSession") == 0)
- {
- g_debug ("Received CancelEndSession");
- }
- else if (strcmp (signal_name, "EndSession") == 0)
- {
- g_debug ("Received EndSession");
- gtk_application_quit_response (app, TRUE, NULL);
- unregister_client (app);
- g_application_quit (G_APPLICATION (app));
- }
- else if (strcmp (signal_name, "Stop") == 0)
- {
- g_debug ("Received Stop");
- unregister_client (app);
- g_application_quit (G_APPLICATION (app));
- }
-}
-
-static void
-gtk_application_startup_session_dbus (GtkApplication *app)
-{
- static gchar *client_id;
- GError *error = NULL;
- GVariant *res;
-
- if (app->priv->session_bus == NULL)
- return;
-
- if (client_id == NULL)
- {
- const gchar *desktop_autostart_id;
-
- desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
- /* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to
- * use the same client id.
- */
- g_unsetenv ("DESKTOP_AUTOSTART_ID");
- client_id = g_strdup (desktop_autostart_id ? desktop_autostart_id : "");
- }
-
- g_debug ("Connecting to session manager");
-
- app->priv->sm_proxy = g_dbus_proxy_new_sync (app->priv->session_bus,
- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
- G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
- NULL,
- "org.gnome.SessionManager",
- "/org/gnome/SessionManager",
- "org.gnome.SessionManager",
- NULL,
- &error);
- if (error)
- {
- g_warning ("Failed to get a session proxy: %s", error->message);
- g_error_free (error);
- return;
- }
-
- /* FIXME: should we reuse the D-Bus application id here ? */
- app->priv->app_id = g_strdup (g_get_prgname ());
-
- if (!app->priv->register_session)
- return;
-
- g_debug ("Registering client '%s' '%s'", app->priv->app_id, client_id);
-
- res = g_dbus_proxy_call_sync (app->priv->sm_proxy,
- "RegisterClient",
- g_variant_new ("(ss)", app->priv->app_id, client_id),
- G_DBUS_CALL_FLAGS_NONE,
- G_MAXINT,
- NULL,
- &error);
-
- if (error)
- {
- g_warning ("Failed to register client: %s", error->message);
- g_error_free (error);
- g_clear_object (&app->priv->sm_proxy);
- return;
- }
-
- g_variant_get (res, "(o)", &app->priv->client_path);
- g_variant_unref (res);
-
- g_debug ("Registered client at '%s'", app->priv->client_path);
-
- app->priv->client_proxy = g_dbus_proxy_new_sync (app->priv->session_bus, 0,
- NULL,
- "org.gnome.SessionManager",
- app->priv->client_path,
- "org.gnome.SessionManager.ClientPrivate",
- NULL,
- &error);
- if (error)
- {
- g_warning ("Failed to get client proxy: %s", error->message);
- g_error_free (error);
- g_clear_object (&app->priv->sm_proxy);
- g_free (app->priv->client_path);
- app->priv->client_path = NULL;
- return;
- }
-
- g_signal_connect (app->priv->client_proxy, "g-signal", G_CALLBACK (client_proxy_signal), app);
-}
-
-
-
/**
* GtkApplicationInhibitFlags:
* @GTK_APPLICATION_INHIBIT_LOGOUT: Inhibit ending the user session
GtkApplicationInhibitFlags flags,
const gchar *reason)
{
- GVariant *res;
- GError *error = NULL;
- guint cookie;
- guint xid = 0;
-
g_return_val_if_fail (GTK_IS_APPLICATION (application), 0);
g_return_val_if_fail (!g_application_get_is_remote (G_APPLICATION (application)), 0);
- if (application->priv->sm_proxy == NULL)
- return 0;
-
- if (window != NULL)
- {
- GdkWindow *gdkwindow;
-
- gdkwindow = gtk_widget_get_window (GTK_WIDGET (window));
- if (gdkwindow == NULL)
- g_warning ("Inhibit called with an unrealized window");
-#ifdef GDK_WINDOWING_X11
- else if (GDK_IS_X11_WINDOW (gdkwindow))
- xid = GDK_WINDOW_XID (gdkwindow);
-#endif
- }
-
- res = g_dbus_proxy_call_sync (application->priv->sm_proxy,
- "Inhibit",
- g_variant_new ("(susu)",
- application->priv->app_id,
- xid,
- reason,
- flags),
- G_DBUS_CALL_FLAGS_NONE,
- G_MAXINT,
- NULL,
- &error);
- if (error)
- {
- g_warning ("Calling Inhibit failed: %s", error->message);
- g_error_free (error);
- return 0;
- }
-
- g_variant_get (res, "(u)", &cookie);
- g_variant_unref (res);
-
- return cookie;
+ return gtk_application_impl_inhibit (application->priv->impl, window, flags, reason);
}
/**
g_return_if_fail (!g_application_get_is_remote (G_APPLICATION (application)));
g_return_if_fail (cookie > 0);
- /* Application could only obtain a cookie through a session
- * manager proxy, so it's valid to assert its presence here. */
- g_return_if_fail (application->priv->sm_proxy != NULL);
-
- g_dbus_proxy_call (application->priv->sm_proxy,
- "Uninhibit",
- g_variant_new ("(u)", cookie),
- G_DBUS_CALL_FLAGS_NONE,
- G_MAXINT,
- NULL, NULL, NULL);
+ gtk_application_impl_uninhibit (application->priv->impl, cookie);
}
/**
gtk_application_is_inhibited (GtkApplication *application,
GtkApplicationInhibitFlags flags)
{
- GVariant *res;
- GError *error = NULL;
- gboolean inhibited;
-
g_return_val_if_fail (GTK_IS_APPLICATION (application), FALSE);
g_return_val_if_fail (!g_application_get_is_remote (G_APPLICATION (application)), FALSE);
- if (application->priv->sm_proxy == NULL)
- return FALSE;
-
- res = g_dbus_proxy_call_sync (application->priv->sm_proxy,
- "IsInhibited",
- g_variant_new ("(u)", flags),
- G_DBUS_CALL_FLAGS_NONE,
- G_MAXINT,
- NULL,
- &error);
- if (error)
- {
- g_warning ("Calling IsInhibited failed: %s", error->message);
- g_error_free (error);
- return FALSE;
- }
-
- g_variant_get (res, "(b)", &inhibited);
- g_variant_unref (res);
-
- return inhibited;
-}
-
-#elif defined(GDK_WINDOWING_QUARTZ)
-
-/* OS X implementation copied from EggSMClient, but simplified since
- * it doesn't need to interact with the user.
- */
-
-static gboolean
-idle_will_quit (gpointer data)
-{
- GtkApplication *app = data;
-
- if (app->priv->quit_inhibit == 0)
- g_application_quit (G_APPLICATION (app));
- else
- {
- GtkApplicationQuartzInhibitor *inhibitor;
- GSList *iter;
- GtkWidget *dialog;
-
- for (iter = app->priv->inhibitors; iter; iter = iter->next)
- {
- inhibitor = iter->data;
- if (inhibitor->flags & GTK_APPLICATION_INHIBIT_LOGOUT)
- break;
- }
- g_assert (inhibitor != NULL);
-
- dialog = gtk_message_dialog_new (inhibitor->window,
- GTK_DIALOG_MODAL,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK,
- _("%s cannot quit at this time:\n\n%s"),
- g_get_application_name (),
- inhibitor->reason);
- g_signal_connect_swapped (dialog,
- "response",
- G_CALLBACK (gtk_widget_destroy),
- dialog);
- gtk_widget_show_all (dialog);
- }
-
- return G_SOURCE_REMOVE;
-}
-
-static pascal OSErr
-quit_requested (const AppleEvent *aevt,
- AppleEvent *reply,
- long refcon)
-{
- GtkApplication *app = GSIZE_TO_POINTER ((gsize)refcon);
-
- /* Don't emit the "quit" signal immediately, since we're
- * called from a weird point in the guts of gdkeventloop-quartz.c
- */
- g_idle_add_full (G_PRIORITY_DEFAULT, idle_will_quit, app, NULL);
-
- return app->priv->quit_inhibit == 0 ? noErr : userCanceledErr;
+ return gtk_application_impl_is_inhibited (application->priv->impl, flags);
}
-static void
-gtk_application_startup_session_quartz (GtkApplication *app)
-{
- if (app->priv->register_session)
- AEInstallEventHandler (kCoreEventClass, kAEQuitApplication,
- NewAEEventHandlerUPP (quit_requested),
- (long)GPOINTER_TO_SIZE (app), false);
-}
-
-guint
-gtk_application_inhibit (GtkApplication *application,
- GtkWindow *window,
- GtkApplicationInhibitFlags flags,
- const gchar *reason)
-{
- GtkApplicationQuartzInhibitor *inhibitor;
-
- g_return_val_if_fail (GTK_IS_APPLICATION (application), 0);
- g_return_val_if_fail (flags != 0, 0);
-
- inhibitor = g_slice_new (GtkApplicationQuartzInhibitor);
- inhibitor->cookie = ++application->priv->next_cookie;
- inhibitor->flags = flags;
- inhibitor->reason = g_strdup (reason);
- inhibitor->window = window ? g_object_ref (window) : NULL;
-
- application->priv->inhibitors = g_slist_prepend (application->priv->inhibitors, inhibitor);
-
- if (flags & GTK_APPLICATION_INHIBIT_LOGOUT)
- application->priv->quit_inhibit++;
-
- return inhibitor->cookie;
-}
-
-void
-gtk_application_uninhibit (GtkApplication *application,
- guint cookie)
-{
- GSList *iter;
-
- for (iter = application->priv->inhibitors; iter; iter = iter->next)
- {
- GtkApplicationQuartzInhibitor *inhibitor = iter->data;
-
- if (inhibitor->cookie == cookie)
- {
- if (inhibitor->flags & GTK_APPLICATION_INHIBIT_LOGOUT)
- application->priv->quit_inhibit--;
- gtk_application_quartz_inhibitor_free (inhibitor);
- application->priv->inhibitors = g_slist_delete_link (application->priv->inhibitors, iter);
- return;
- }
- }
-
- g_warning ("Invalid inhibitor cookie");
-}
-
-gboolean
-gtk_application_is_inhibited (GtkApplication *application,
- GtkApplicationInhibitFlags flags)
-{
- if (flags & GTK_APPLICATION_INHIBIT_LOGOUT)
- return application->priv->quit_inhibit > 0;
-
- return FALSE;
-}
-
-#else
-
-/* Trivial implementation.
- *
- * For the inhibit API on Windows, see
- * http://msdn.microsoft.com/en-us/library/ms700677%28VS.85%29.aspx
- */
-
-guint
-gtk_application_inhibit (GtkApplication *application,
- GtkWindow *window,
- GtkApplicationInhibitFlags flags,
- const gchar *reason)
-{
- return 0;
-}
-
-void
-gtk_application_uninhibit (GtkApplication *application,
- guint cookie)
-{
-}
-
-gboolean
-gtk_application_is_inhibited (GtkApplication *application,
- GtkApplicationInhibitFlags flags)
-{
- return FALSE;
-}
-
-#endif
-
GtkActionMuxer *
gtk_application_get_parent_muxer_for_window (GtkWindow *window)
{
return accels;
}
+
+GtkActionMuxer *
+gtk_application_get_action_muxer (GtkApplication *application)
+{
+ g_assert (application->priv->muxer);
+
+ return application->priv->muxer;
+}
+
+void
+gtk_application_handle_window_realize (GtkApplication *application,
+ GtkWindow *window)
+{
+ gtk_application_impl_handle_window_realize (application->priv->impl, window);
+}
+
+void
+gtk_application_handle_window_map (GtkApplication *application,
+ GtkWindow *window)
+{
+ gtk_application_impl_handle_window_map (application->priv->impl, window);
+}
--- /dev/null
+/*
+ * Copyright © 2013 Canonical Limited
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "config.h"
+
+#include "gtkapplicationprivate.h"
+
+#ifdef GDK_WINDOWING_X11
+#include <gdk/x11/gdkx.h>
+#endif
+
+#ifdef GDK_WINDOWING_WAYLAND
+#include <gdk/wayland/gdkwayland.h>
+#endif
+
+#ifdef GDK_WINDOWING_QUARTZ
+#include <gdk/quartz/gdkquartz.h>
+#endif
+
+G_DEFINE_TYPE (GtkApplicationImpl, gtk_application_impl, G_TYPE_OBJECT)
+
+static void
+gtk_application_impl_init (GtkApplicationImpl *impl)
+{
+}
+
+static guint do_nothing (void) { return 0; }
+
+static void
+gtk_application_impl_class_init (GtkApplicationImplClass *class)
+{
+ /* NB: can only 'do_nothing' for functions with integer or void return */
+ class->startup = (gpointer) do_nothing;
+ class->shutdown = (gpointer) do_nothing;
+ class->before_emit = (gpointer) do_nothing;
+ class->window_added = (gpointer) do_nothing;
+ class->window_removed = (gpointer) do_nothing;
+ class->active_window_changed = (gpointer) do_nothing;
+ class->handle_window_realize = (gpointer) do_nothing;
+ class->handle_window_map = (gpointer) do_nothing;
+ class->set_app_menu = (gpointer) do_nothing;
+ class->set_menubar = (gpointer) do_nothing;
+ class->inhibit = (gpointer) do_nothing;
+ class->uninhibit = (gpointer) do_nothing;
+ class->is_inhibited = (gpointer) do_nothing;
+}
+
+void
+gtk_application_impl_startup (GtkApplicationImpl *impl,
+ gboolean register_session)
+{
+ GTK_APPLICATION_IMPL_GET_CLASS (impl)->startup (impl, register_session);
+}
+
+void
+gtk_application_impl_shutdown (GtkApplicationImpl *impl)
+{
+ GTK_APPLICATION_IMPL_GET_CLASS (impl)->shutdown (impl);
+}
+
+void
+gtk_application_impl_before_emit (GtkApplicationImpl *impl,
+ GVariant *platform_data)
+{
+ GTK_APPLICATION_IMPL_GET_CLASS (impl)->before_emit (impl, platform_data);
+}
+
+void
+gtk_application_impl_window_added (GtkApplicationImpl *impl,
+ GtkWindow *window)
+{
+ GTK_APPLICATION_IMPL_GET_CLASS (impl)->window_added (impl, window);
+}
+
+void
+gtk_application_impl_window_removed (GtkApplicationImpl *impl,
+ GtkWindow *window)
+{
+ GTK_APPLICATION_IMPL_GET_CLASS (impl)->window_removed (impl, window);
+}
+
+void
+gtk_application_impl_active_window_changed (GtkApplicationImpl *impl,
+ GtkWindow *window)
+{
+ GTK_APPLICATION_IMPL_GET_CLASS (impl)->active_window_changed (impl, window);
+}
+
+void
+gtk_application_impl_handle_window_realize (GtkApplicationImpl *impl,
+ GtkWindow *window)
+{
+ GTK_APPLICATION_IMPL_GET_CLASS (impl)->handle_window_realize (impl, window);
+}
+
+void
+gtk_application_impl_handle_window_map (GtkApplicationImpl *impl,
+ GtkWindow *window)
+{
+ GTK_APPLICATION_IMPL_GET_CLASS (impl)->handle_window_map (impl, window);
+}
+
+void
+gtk_application_impl_set_app_menu (GtkApplicationImpl *impl,
+ GMenuModel *app_menu)
+{
+ GTK_APPLICATION_IMPL_GET_CLASS (impl)->set_app_menu (impl, app_menu);
+}
+
+void
+gtk_application_impl_set_menubar (GtkApplicationImpl *impl,
+ GMenuModel *menubar)
+{
+ GTK_APPLICATION_IMPL_GET_CLASS (impl)->set_menubar (impl, menubar);
+}
+
+guint
+gtk_application_impl_inhibit (GtkApplicationImpl *impl,
+ GtkWindow *window,
+ GtkApplicationInhibitFlags flags,
+ const gchar *reason)
+{
+ return GTK_APPLICATION_IMPL_GET_CLASS (impl)->inhibit (impl, window, flags, reason);
+}
+
+void
+gtk_application_impl_uninhibit (GtkApplicationImpl *impl,
+ guint cookie)
+{
+ GTK_APPLICATION_IMPL_GET_CLASS (impl)->uninhibit (impl, cookie);
+}
+
+gboolean
+gtk_application_impl_is_inhibited (GtkApplicationImpl *impl,
+ GtkApplicationInhibitFlags flags)
+{
+ return GTK_APPLICATION_IMPL_GET_CLASS (impl)->is_inhibited (impl, flags);
+}
+
+GtkApplicationImpl *
+gtk_application_impl_new (GtkApplication *application,
+ GdkDisplay *display)
+{
+ GtkApplicationImpl *impl;
+ GType impl_type;
+
+ impl_type = gtk_application_impl_get_type ();
+
+#ifdef GDK_WINDOWING_X11
+ if (GDK_IS_X11_DISPLAY (display))
+ impl_type = gtk_application_impl_x11_get_type ();
+#endif
+
+#ifdef GDK_WINDOWING_WAYLAND
+ if (GDK_IS_WAYLAND_DISPLAY (display))
+ impl_type = gtk_application_impl_wayland_get_type ();
+#endif
+
+#ifdef GDK_WINDOWING_QUARTZ
+ if (GDK_IS_QUARTZ_DISPLAY (display))
+ impl_type = gtk_application_impl_quartz_get_type ();
+#endif
+
+ impl = g_object_new (impl_type, NULL);
+ impl->application = application;
+ impl->display = display;
+
+ return impl;
+}
/*
- * Copyright © 2011 Canonical Limited
+ * Copyright © 2011, 2013 Canonical Limited
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#include "gtkactionmuxer.h"
G_GNUC_INTERNAL
-gboolean gtk_application_window_publish (GtkApplicationWindow *window,
- GDBusConnection *session,
- const gchar *object_path,
- guint object_id);
-
+void gtk_application_window_set_id (GtkApplicationWindow *window,
+ guint id);
G_GNUC_INTERNAL
-void gtk_application_window_unpublish (GtkApplicationWindow *window);
-
+GActionGroup * gtk_application_window_get_action_group (GtkApplicationWindow *window);
G_GNUC_INTERNAL
-GtkAccelGroup * gtk_application_window_get_accel_group (GtkApplicationWindow *window);
-
+void gtk_application_handle_window_realize (GtkApplication *application,
+ GtkWindow *window);
G_GNUC_INTERNAL
-const gchar * gtk_application_get_app_menu_object_path (GtkApplication *application);
-G_GNUC_INTERNAL
-const gchar * gtk_application_get_menubar_object_path (GtkApplication *application);
-
+void gtk_application_handle_window_map (GtkApplication *application,
+ GtkWindow *window);
G_GNUC_INTERNAL
GtkActionMuxer * gtk_application_get_parent_muxer_for_window (GtkWindow *window);
GtkWindow *window,
GtkWindowKeysForeachFunc callback,
gpointer user_data);
+G_GNUC_INTERNAL
+GtkActionMuxer * gtk_application_get_action_muxer (GtkApplication *application);
+
+
+#define GTK_TYPE_APPLICATION_IMPL (gtk_application_impl_get_type ())
+#define GTK_APPLICATION_IMPL_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \
+ GTK_TYPE_APPLICATION_IMPL, \
+ GtkApplicationImplClass))
+#define GTK_APPLICATION_IMPL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GTK_TYPE_APPLICATION_IMPL, \
+ GtkApplicationImplClass))
+
+typedef struct
+{
+ GObject parent_instance;
+ GtkApplication *application;
+ GdkDisplay *display;
+} GtkApplicationImpl;
+
+typedef struct
+{
+ GObjectClass parent_class;
+
+ void (* startup) (GtkApplicationImpl *impl,
+ gboolean register_session);
+ void (* shutdown) (GtkApplicationImpl *impl);
+
+ void (* before_emit) (GtkApplicationImpl *impl,
+ GVariant *platform_data);
+
+ void (* window_added) (GtkApplicationImpl *impl,
+ GtkWindow *window);
+ void (* window_removed) (GtkApplicationImpl *impl,
+ GtkWindow *window);
+ void (* active_window_changed) (GtkApplicationImpl *impl,
+ GtkWindow *window);
+ void (* handle_window_realize) (GtkApplicationImpl *impl,
+ GtkWindow *window);
+ void (* handle_window_map) (GtkApplicationImpl *impl,
+ GtkWindow *window);
+
+ void (* set_app_menu) (GtkApplicationImpl *impl,
+ GMenuModel *app_menu);
+ void (* set_menubar) (GtkApplicationImpl *impl,
+ GMenuModel *menubar);
+
+ guint (* inhibit) (GtkApplicationImpl *impl,
+ GtkWindow *window,
+ GtkApplicationInhibitFlags flags,
+ const gchar *reason);
+ void (* uninhibit) (GtkApplicationImpl *impl,
+ guint cookie);
+ gboolean (* is_inhibited) (GtkApplicationImpl *impl,
+ GtkApplicationInhibitFlags flags);
+
+
+} GtkApplicationImplClass;
+
+#define GTK_TYPE_APPLICATION_IMPL_DBUS (gtk_application_impl_dbus_get_type ())
+#define GTK_APPLICATION_IMPL_DBUS_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \
+ GTK_TYPE_APPLICATION_IMPL_DBUS, \
+ GtkApplicationImplDBusClass))
+#define GTK_APPLICATION_IMPL_DBUS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GTK_TYPE_APPLICATION_IMPL_DBUS, \
+ GtkApplicationImplDBusClass))
+
+typedef struct
+{
+ GtkApplicationImpl impl;
+
+ GDBusConnection *session;
+
+ const gchar *application_id;
+ const gchar *unique_name;
+ const gchar *object_path;
+
+ gchar *app_menu_path;
+ guint app_menu_id;
+
+ gchar *menubar_path;
+ guint menubar_id;
+
+ /* Session management... */
+ gchar *app_id; /* actually prgname... */
+ GDBusProxy *sm_proxy;
+ GDBusProxy *client_proxy;
+ gchar *client_path;
+} GtkApplicationImplDBus;
+
+typedef struct
+{
+ GtkApplicationImplClass parent_class;
+
+ /* returns floating */
+ GVariant * (* get_window_system_id) (GtkApplicationImplDBus *dbus,
+ GtkWindow *window);
+} GtkApplicationImplDBusClass;
+
+G_GNUC_INTERNAL
+GType gtk_application_impl_get_type (void);
+G_GNUC_INTERNAL
+GType gtk_application_impl_dbus_get_type (void);
+G_GNUC_INTERNAL
+GType gtk_application_impl_x11_get_type (void);
+G_GNUC_INTERNAL
+GType gtk_application_impl_wayland_get_type (void);
+G_GNUC_INTERNAL
+GType gtk_application_impl_quartz_get_type (void);
+
+G_GNUC_INTERNAL
+GtkApplicationImpl * gtk_application_impl_new (GtkApplication *application,
+ GdkDisplay *display);
+G_GNUC_INTERNAL
+void gtk_application_impl_startup (GtkApplicationImpl *impl,
+ gboolean register_sesion);
+G_GNUC_INTERNAL
+void gtk_application_impl_shutdown (GtkApplicationImpl *impl);
+G_GNUC_INTERNAL
+void gtk_application_impl_before_emit (GtkApplicationImpl *impl,
+ GVariant *platform_data);
+G_GNUC_INTERNAL
+void gtk_application_impl_window_added (GtkApplicationImpl *impl,
+ GtkWindow *window);
+G_GNUC_INTERNAL
+void gtk_application_impl_window_removed (GtkApplicationImpl *impl,
+ GtkWindow *window);
+G_GNUC_INTERNAL
+void gtk_application_impl_active_window_changed (GtkApplicationImpl *impl,
+ GtkWindow *window);
+G_GNUC_INTERNAL
+void gtk_application_impl_handle_window_realize (GtkApplicationImpl *impl,
+ GtkWindow *window);
+G_GNUC_INTERNAL
+void gtk_application_impl_handle_window_map (GtkApplicationImpl *impl,
+ GtkWindow *window);
+G_GNUC_INTERNAL
+void gtk_application_impl_set_app_menu (GtkApplicationImpl *impl,
+ GMenuModel *app_menu);
+G_GNUC_INTERNAL
+void gtk_application_impl_set_menubar (GtkApplicationImpl *impl,
+ GMenuModel *menubar);
+G_GNUC_INTERNAL
+guint gtk_application_impl_inhibit (GtkApplicationImpl *impl,
+ GtkWindow *window,
+ GtkApplicationInhibitFlags flags,
+ const gchar *reason);
+G_GNUC_INTERNAL
+void gtk_application_impl_uninhibit (GtkApplicationImpl *impl,
+ guint cookie);
+G_GNUC_INTERNAL
+gboolean gtk_application_impl_is_inhibited (GtkApplicationImpl *impl,
+ GtkApplicationInhibitFlags flags);
+
+G_GNUC_INTERNAL
+gchar * gtk_application_impl_dbus_get_window_path (GtkApplicationImplDBus *dbus,
+ GtkWindow *window);
#endif /* __GTK_APPLICATION_PRIVATE_H__ */
#include "gtkintl.h"
#include "gtksettings.h"
-#include <gdk/gdk.h>
-#ifdef GDK_WINDOWING_X11
-#include <gdk/x11/gdkx.h>
-#endif
-#ifdef GDK_WINDOWING_WAYLAND
-#include <gdk/wayland/gdkwayland.h>
-#endif
-
#ifdef HAVE_GIO_UNIX
#include <gio/gdesktopappinfo.h>
#endif
GMenu *app_menu_section;
GMenu *menubar_section;
- GDBusConnection *session;
- gchar *object_path;
- guint export_id;
-
guint id;
};
gtk_application_window_real_realize (GtkWidget *widget)
{
GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (widget);
- GtkApplication *application;
GtkSettings *settings;
- application = gtk_window_get_application (GTK_WINDOW (window));
settings = gtk_widget_get_settings (widget);
g_signal_connect (settings, "notify::gtk-shell-shows-app-menu",
gtk_application_window_update_shell_shows_app_menu (window, settings);
gtk_application_window_update_shell_shows_menubar (window, settings);
gtk_application_window_update_menubar (window);
-
-#ifdef GDK_WINDOWING_X11
- {
- GdkWindow *gdkwindow;
-
- gdkwindow = gtk_widget_get_window (GTK_WIDGET (window));
-
- if (GDK_IS_X11_WINDOW (gdkwindow) && window->priv->session)
- {
- gdk_x11_window_set_utf8_property (gdkwindow, "_GTK_APPLICATION_ID",
- g_application_get_application_id (G_APPLICATION (application)));
-
- gdk_x11_window_set_utf8_property (gdkwindow, "_GTK_UNIQUE_BUS_NAME",
- g_dbus_connection_get_unique_name (window->priv->session));
-
- gdk_x11_window_set_utf8_property (gdkwindow, "_GTK_APPLICATION_OBJECT_PATH",
- g_application_get_dbus_object_path (G_APPLICATION (application)));
-
- gdk_x11_window_set_utf8_property (gdkwindow, "_GTK_WINDOW_OBJECT_PATH",
- window->priv->object_path);
-
- gdk_x11_window_set_utf8_property (gdkwindow, "_GTK_APP_MENU_OBJECT_PATH",
- gtk_application_get_app_menu_object_path (application));
-
- gdk_x11_window_set_utf8_property (gdkwindow, "_GTK_MENUBAR_OBJECT_PATH",
- gtk_application_get_menubar_object_path (application));
- }
- }
-#endif
}
static void
GTK_WIDGET_CLASS (gtk_application_window_parent_class)->unrealize (widget);
}
-gboolean
-gtk_application_window_publish (GtkApplicationWindow *window,
- GDBusConnection *session,
- const gchar *object_path,
- guint object_id)
+GActionGroup *
+gtk_application_window_get_action_group (GtkApplicationWindow *window)
{
- g_assert (window->priv->session == NULL);
- g_assert (window->priv->export_id == 0);
- g_assert (window->priv->object_path == NULL);
- g_assert (window->priv->id == 0);
-
- window->priv->export_id = g_dbus_connection_export_action_group (session, object_path,
- G_ACTION_GROUP (window->priv->actions),
- NULL);
-
- if (window->priv->export_id == 0)
- return FALSE;
-
- window->priv->session = session;
- window->priv->object_path = g_strdup (object_path);
- window->priv->id = object_id;
-
- return TRUE;
-}
-
-void
-gtk_application_window_unpublish (GtkApplicationWindow *window)
-{
- g_assert (window->priv->session != NULL);
- g_assert (window->priv->export_id != 0);
- g_assert (window->priv->object_path != NULL);
- g_assert (window->priv->id != 0);
-
- g_dbus_connection_unexport_action_group (window->priv->session, window->priv->export_id);
- window->priv->session = NULL;
- window->priv->export_id = 0;
- window->priv->id = 0;
-
- g_free (window->priv->object_path);
- window->priv->object_path = NULL;
+ return G_ACTION_GROUP (window->priv->actions);
}
static void
gtk_widget_map (window->priv->menubar);
GTK_WIDGET_CLASS (gtk_application_window_parent_class)->map (widget);
-
-#ifdef GDK_WINDOWING_WAYLAND
- {
- GdkWindow *gdkwindow;
- GtkApplication *application;
-
- application = gtk_window_get_application (GTK_WINDOW (window));
- gdkwindow = gtk_widget_get_window (widget);
-
- if (GDK_IS_WAYLAND_WINDOW (gdkwindow) && window->priv->session)
- {
- gdk_wayland_window_set_dbus_properties_libgtk_only (gdkwindow,
- g_application_get_application_id (G_APPLICATION (application)),
- gtk_application_get_app_menu_object_path (application),
- gtk_application_get_menubar_object_path (application),
- window->priv->object_path,
- g_application_get_dbus_object_path (G_APPLICATION (application)),
- g_dbus_connection_get_unique_name (window->priv->session));
- }
- }
-#endif
}
static void
return window->priv->id;
}
+
+void
+gtk_application_window_set_id (GtkApplicationWindow *window,
+ guint id)
+{
+ g_return_if_fail (GTK_IS_APPLICATION_WINDOW (window));
+ window->priv->id = id;
+}
gtk_window_set_focus_visible (window, gtk_window_get_focus_visible (priv->transient_parent));
else
gtk_window_set_focus_visible (window, FALSE);
+
+ if (priv->application)
+ gtk_application_handle_window_map (priv->application, window);
}
static gboolean
}
#endif
+ if (priv->application)
+ gtk_application_handle_window_realize (priv->application, window);
+
/* Icons */
gtk_window_realize_icon (window);